package org.symkom.graph;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Point2D;
import java.util.List;

import javax.swing.JPanel;

public class Graph extends JPanel implements MouseMotionListener, MouseListener{
	
	int width;
	int height;
	int startX;
	int startY;
	
	//mouse
	int mx;
	int my;
	int smx;
	int smy;
	int posX;
	int posY;

	static public final double SCALE_X = 10;
	static public final double SCALE_Y = 10;
	static public final double SCALE_STEP = 2;
	
	static public double scaleX = SCALE_X;
	static public double scaleY = SCALE_Y;

	static final double margin = 10;
	
	List<Point2D> points;
	
	public Graph(int w, int h) {
		width = w;
		height = h;
		setPreferredSize(new Dimension(w, h));
		addMouseMotionListener(this);
		addMouseListener(this);
		setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
	}
	public void setPoints(List<Point2D> points) {
		this.points = points;
			
		startX = width/2;
		startY = height/2;
	}
	public void paintComponent(Graphics g) {
		super.paintComponents(g);
		Graphics2D g2 = (Graphics2D) g;
        
		
		g.setColor(Color.WHITE);
		g.fillRect(0, 0, width, height);
		g.setColor(Color.black);
		g.drawRect(0, 0, width-1, height-1);
		//kratka
        g.setColor(Color.GRAY);
        int scx = (int)(10*scaleX);
        int h2 = height/2;
        for(int i = 0 ; i < h2 + 1 ; i += scx) {
        		int mh = my%scx;
  
                g.drawLine(0, mh +  h2+i, width, mh + h2+i);
                g.drawLine(0, mh + h2-i, width, mh + h2-i);
        }
        int scy = (int)(10*scaleY);
        int w2 = width/2;
        for(int i = 0 ; i < w2 + 1 ; i += scy) {
        		int mw = mx%scy;
                g.drawLine(mw + w2+i, 0, mw + w2+i, height);
                g.drawLine(mw + w2-i, 0, mw + w2-i, height);
        }
		
		g.setColor(Color.black);
		g2.setStroke(new BasicStroke(2));
		g2.drawLine(0, my + startY, width, my + startY);
		g2.drawLine(mx + startX, 0, mx + startX, height);
				
		//pozycja myszki
		g2.setColor(Color.red);
		g2.setFont(new Font(null, Font.BOLD, 20));
		g2.drawString("("+posX+", "+posY+")", 10, 20);
		
		if(points == null) return;
		
		for(int i = 0 ; i < points.size() -1 ; i++) {
			double sx = mx + startX + points.get(i).getX()*scaleY;
			double sy = my + startY - points.get(i).getY()*scaleX;
			double ex = mx + startX + points.get(i+1).getX()*scaleY;
			double ey = my + startY - points.get(i+1).getY()*scaleX;
			
			g2.setColor(Color.blue);
			g2.setStroke(new BasicStroke(3));
			g2.drawLine((int)sx, (int)sy , (int)ex, (int)ey);
		}
	}
	@Override
	public void mouseDragged(MouseEvent e) {
		mx = e.getX() - smx;
		my = e.getY() - smy;
				
		revalidate();
		repaint();
	}
	@Override
	public void mouseMoved(MouseEvent e) {
		posX = -(mx - e.getX() + startX);
		posY = my - e.getY() + startY;
		//na odwrot... wtf
		posX /= (scaleY/10);
		posY /= (scaleX/10);


		revalidate();
		repaint();
	}
	@Override
	public void mouseClicked(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void mouseEntered(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void mouseExited(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void mousePressed(MouseEvent e) {
		smx = e.getX() - mx;
		smy = e.getY() - my;
		setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
		
	}
	@Override
	public void mouseReleased(MouseEvent e) {
		setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
		
	}
//	private int minimumY() {
//        double min = points.get(0).getY();
//        
//        for(Point2D p : points)
//                if(min > p.getY())
//                        min = p.getY();
//        return (int)min * (int)scaleY;             
//	}
//	private int maximumY() {
//        double max = points.get(0).getY();
//        
//        for(Point2D p : points)
//                if(max < p.getY())
//                        max = p.getY();
//        return (int)max * (int)scaleY;             
//	}
//	private int minimumX() {
//   
//        return (int)points.get(0).getX() * (int)scaleX;             
//	}
//	private int maximumX() {
//        return (int)points.get(points.size()-1).getX() * (int)scaleX;             
//	}

}
